#*******************************************************************************
# Park file, keeps specific information about a wind park together
# Not sure about the implementation, it is kind of mimicking
# object-oriented programming but using .py files instead of objects
#
# Really not sure whether we should be defining different read() methods
# but each park has slightly different set of variables
#*******************************************************************************

import numpy as np
import matplotlib as mpl
import tables as tb
from powercurve import powercurve

h5fname        = 'C:\UnBackedUp_Data\h5\lillgrund_10_minute_array.h5'
name           = 'lillgrund'
turbine_pcurve = powercurve.fromfile1D(r'H:\Data\pcurves\turbine\siemems_swt.csv')
interval  = '10m'

tbids =     ['SLGA01', 'SLGA02', 'SLGA03', 'SLGA04', 'SLGA05', 'SLGA06', 'SLGA07',
              'SLGB01', 'SLGB02', 'SLGB03', 'SLGB04', 'SLGB05', 'SLGB06', 'SLGB07', 'SLGB08',
              'SLGC01', 'SLGC02', 'SLGC03', 'SLGC04', 'SLGC05', 'SLGC06', 'SLGC07', 'SLGC08',
              'SLGD01', 'SLGD02', 'SLGD03', 'SLGD04', 'SLGD06', 'SLGD07', 'SLGD08',
              'SLGE01', 'SLGE02', 'SLGE03', 'SLGE04', 'SLGE06', 'SLGE07',
              'SLGF02', 'SLGF03', 'SLGF04', 'SLGF05', 'SLGF06',
              'SLGG02', 'SLGG03', 'SLGG04', 'SLGG05',
              'SLGH02', 'SLGH03', 'SLGH04']

vtable  = {'WindSpeed':         'WindSpeed',
          'ActivePower':        'ActivePower',
          'BladeAngleA':        'BladePitchAngle',
          'NacelleDirection':   'NacelleDirection'}

#
# Used for drawing direction indicators on plots
#
pairs = [('SLGD08', 'SLGC08'), ('SLGD08', 'SLGD07'), ('SLGD08', 'SLGE07')]


def front_row(d):

    if    0 <= d and d <= 45:   x = [0,7, 15, 23, 41, 45]
    elif 45 <= d and d <= 90:   x = [0,1,7,15,23,30]
    elif 90 <= d and d <= 135:  x = [0,1,2,3,4,5,6,14]
    elif 135 <= d and d <= 180: x = [0,1,2,3,4,5,6,14]
    elif 180 <= d and d <= 225: x = [6,14,22,29]
    elif 225 <= d and d <= 270: x = [14, 22, 29, 35, 40, 44, 47]
    elif 270 <= d and d <= 315: x = [35, 40, 44, 45, 46, 47]
    elif 315 <= d and d <= 360: x = [30, 45, 46, 47]
    else: raise Exception('To Err is human')

    l = [tbids[xi] for xi in x]
    return l

def read_turbines():
    h5f         = tb.openFile(h5fname, mode='r')

    #
    # Turbine variables
    #
    group       = h5f.root.turbines
    tbids       = group.tbid.read()
    dates       = group.utctimestamp.read()
    timestamp   = np.array(mpl.dates.num2date(dates))
    pwr         = np.ma.array(group.activepower.read())
    spd         = np.ma.array(group.windspeed.read())
    yaw         = np.ma.array(group.yawdirection.read())
    pitch       = np.ma.array(group.bladeanglea.read())

    #
    # First mask any non-sensical data
    #
    yaw.mask   = yaw<0
    spd.mask   = (spd<0) | (np.isnan(spd))

    h5f.close()
    return tbids, timestamp, pwr, yaw, spd, pitch


def read_met():
    h5f         = tb.openFile(h5fname, mode='r')

    #
    # Met variables
    #
    group       = h5f.root.met
    met_spd     = np.ma.array(group.windspeed65.read())
    met_dir     = np.ma.array(group.winddirection61.read())

    met_spd.mask  = met_spd<0
    h5f.close()
    return met_spd, met_dir

